#!/bin/bash
########################################################################
####  Script Name: dsl
####  Description: smxi archive kernel zip file constructor
####  version: 2.3.11
####  Date: 2014-10-09
########################################################################
####  Copyright (C) Harald Hope 2007-2014
####
####  This program is free software; you can redistribute it and/or modify it under
####  the terms of the GNU General Public License as published by the Free Software
####  Foundation; either version 3 of the License, or (at your option) any later version.
####
####  This program is distributed in the hope that it will be useful, but WITHOUT
####  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
####  FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
####
####  Get the full text of the GPL here: http://www.gnu.org/licenses/gpl.txt
########################################################################
#### DEFINE:
#### TRUE: -eq 0; == 'true'; function return 0
#### FALSE: -gt 0; == ''; function return > 0
########################################################################
#### VARIABLES
########################################################################

# layout
LINE='- - - - - - - - - - - - - - - - - - - - - - - - - - - - -'

# paths, change these to suite your needs
SVN_DIR="$HOME/bin/scripts/smxi/svn/trunk"
KERNEL_DIR="$HOME/large/kernel-zips"
KERNEL_SVN_DIR="$SVN_DIR/kernel-stuff/"
KERNEL_INSTALLER_DIR="$KERNEL_DIR/kernel-installer"

# script values
POOL_TYPE='main'
GCC_ALT=''
KERNEL_TYPE='liquorix' # default to this
KERNEL_MAIN=''
KERNEL_WORKING=''
MIRROR_MAIN=''
MIRROR_MODULES=''
MIRROR_EXTRA=''
NEW_KERNEL_DIRECTORY=''

# boolean switches
B_REDO=''
B_SKIP_ZIP=''

########################################################################
#### FUNCTIONS
########################################################################

# args: $1 error nu; $2 - extra data
error_handler()
{
	local message=''

	case $1 in
		1)
			message='You should not be root to run this script'
			;;
		2)
			message="The directory: $2 does not exist, please fix this."
			;;
		3)
			message="You have to have a -k <kernel> to run this, it's not optional: item/line $2"
			;;
		4)
			message="wget download error when downloading: $2"
			;;
		5)
			message="The kernel you are trying to download: $2\ndoes not appear to exist, check your dsl arguments again to make sure they are correct"
			echo "Error in download data: Cleaning up bad directory name prior to exit..."
			rm -fR $NEW_KERNEL_DIRECTORY
			;;
		6)
			message="Missing required packaging file: $2"
			;;
		7)
			message="Corrupted kernel zip file: $2\nRemoved bad file."
			rm -f $2
			;;
		8)
			message="Startup error: $2"
			;;
		9)
			message="Unsupported startup option: $2"
			;;
		10)
			message="You can't run -r and -z together, they are mutually exclusive."
			;;
		11)
			message="Unsupported GCC -g data: $2"
			;;
		12)
			message="You have failed to set non default kernel -s flag"
			;;
		13)
			message="-e is only for aptosid kernels."
			;;
	esac
	echo $LINE
	echo -e $message
	echo "Error $1 - Exiting script, please correct the error"
	echo $LINE
	exit $1
}

get_options()
{
	local opt=''

	if [ -z "$1" ];then
		error_handler 8 'no arguments given'
	fi
	if [ -z "$( grep '^\-' <<< $1 )" ];then
		error_handler 8 "Option: $1 used but must start with a: -"
	fi

	while getopts :efg:hk:lprsz opt
	do
		case $opt in
			a)	KERNEL_TYPE='aptosid'
				;;
			# aptosid only
			e)	POOL_TYPE='exp.main'
				;;
			f)	POOL_TYPE='future'
				;;
			g) if [ -n "$( grep -Es '[3-4]\.[0-9]' <<< $OPTARG )" ];then
					GCC_ALT=$OPTARG
				else
					error_handler 11 "$OPTARG"
				fi
				;;
			k)	KERNEL_WORKING=$OPTARG
				;;
			p)	POOL_TYPE='past'
				;;
			r)	B_REDO='true'
				;;
			
			z)	B_SKIP_ZIP='true'
				;;
			h)
				echo "Useage:
-a Switch to using aptosid as default kernel type.
-e Use exp.main data (aptosid only)
-f Use future data (liquorix only)
-g Use alternate GCC values. Syntax: -g [3-4].[0-9]
-k Kernel to download. Requires -k <3.12-4.lqx.2|2.6.26-8.lqx.2> type syntax
   NOTE: -k <kernel> is required to run dsl always
-p Use past data (liquorix only)
-r Redo zip without downloading again.

-z Download only, no zip creation
"
				exit 0
				;;
			*)
				error_handler 9 "-$OPTARG"
				;;
		esac
	done
	
	if [ "$POOL_TYPE" == 'exp.main' -a "$KERNEL_TYPE" != 'aptosid' ];then
		error_handler 13
	fi
	if [ "$B_REDO" == 'true' -a "$B_SKIP_ZIP" == 'true' ];then
		error_handler 10
	fi
	if [ -z "$KERNEL_WORKING" ];then
		error_handler 3 175
	fi
	# avoid careless errors
	if [ -n "$( grep 'slh' <<< $KERNEL_WORKING )" -a "$KERNEL_TYPE" != 'aptosid' ];then
		error_handler 12
	fi
}

set_values()
{
	local repoPre='' repoMain='' repoModules='' repoExtra=''

	case $KERNEL_TYPE in
		aptosid)
			repoPre="http://aptosid.com/debian/pool/${POOL_TYPE}/l/"
			repoMain='linux-aptosid/'
			repoModules='linux-modules-aptosid-main/'
			repoExtra='linux-kbuild/'
			;;
		liquorix)
			repoPre="http://liquorix.net/debian/pool/${POOL_TYPE}/l/"
			repoMain='linux-liquorix/'
			repoModules='linux-modules-liquorix-main/'
			repoExtra=''
			;;
	esac

	MIRROR_MAIN="$repoPre$repoMain"
	MIRROR_MODULES="$repoPre$repoModules"
	if [ -n "$repoExtra" ];then
		MIRROR_EXTRA="$repoPre$repoExtra"
	fi

	# set directory name
	NEW_KERNEL_DIRECTORY="$KERNEL_DIR/$KERNEL_WORKING"
	# then get the 2.6.28 slice
	KERNEL_MAIN=$( cut -d '-' -f 1 <<< $KERNEL_WORKING )
}

start_up_tests()
{
	local startDir=''

	echo $LINE
	echo "Running initial startup tests..."

	# don't want to use root for this script
	if [ "$(whoami)" == 'root' ];then
		error_handler 1
	fi

	# make sure the paths you made are right and exist
	for startDir in $KERNEL_DIR $KERNEL_INSTALLER_DIR $SVN_DIR
	do
		if [ ! -d "$startDir" ];then
			error_handler 2 $startDir
		fi
	done

	if [ ! -f $KERNEL_INSTALLER_DIR/install-kernel.sh ];then
		error_handler 6 "$KERNEL_INSTALLER_DIR/install-kernel.sh"
	fi

	echo "Start up tests: passed"
}

create_kernel_directory()
{
	echo $LINE
	echo "Starting kernel zip builder..."
	echo "Creating new $NEW_KERNEL_DIRECTORY directory..."

	if [ ! -d $NEW_KERNEL_DIRECTORY ];then
		mkdir $NEW_KERNEL_DIRECTORY
	fi
	cd $NEW_KERNEL_DIRECTORY
}

create_sub_directories()
{
	local directories='32 32-pae 32-meta 64 64-meta kernel-installer-files src-gz kernel-full-zips'
	local redoDirectories='32 32-pae 32-meta 64 64-meta'
	local directory=''

	echo $LINE
	echo 'Generating 32/32-pae/64 bit and meta directories...'
	for directory in $directories
	do
		if [ ! -d $directory ];then
			mkdir $directory
		fi
	done
	if [ "$B_REDO" == 'true' ];then
		echo $LINE
		echo "Restoring original condition of build by moving data back to base directory."
		for directory in $redoDirectories
		do
			echo "Emptying $directory..."
			cd $directory
			mv -f * ../
			cd ../
		done
		rm -f kernel-full-zips/*
	fi
}

check_kernel_exists()
{
	local fileName='tempTesterDsl' kernelExists=''
	local kernelId=''

	case $KERNEL_TYPE in
		aptosid)
			kernelId="linux-image-$KERNEL_WORKING-aptosid-686"
			;;
		liquorix)
			kernelId="linux-image-$KERNEL_WORKING-liquorix-686"
			;;
	esac
	# linux-image-4.1-1.dmz.2-liquorix-686-pae_4.1-2_i386.deb
	# linux-image-4.1-1.dmz.2-liquorix-686_4.1-2_i386.deb
	# linux-image-4.1-1.dmz.2-liquorix-amd64_4.1-2_amd64.deb
	echo $LINE
	echo "Confirming that kernel $KERNEL_WORKING exists on server..."
	wget -O $fileName -q -e robots=off $MIRROR_MAIN

	kernelExists=$( grep -i "$kernelId" $fileName )
	#rm -f $fileName
	if [ -z "$kernelExists" ];then
		error_handler 5 $KERNEL_WORKING
	else
		echo "Kernel appears to exist on remote server, continuing..."
	fi
}

download_kernel_files()
{
	local sleepTime=2

	echo $LINE
	echo "Starting grab of kernel packages now..."
	echo $LINE
	echo $LINE
	echo
	## download kernels and all related debs
	echo "Getting module debs now..."
	wget -r -l3 -Nc -nd -np -A.deb $MIRROR_MODULES -e robots=off # || error_handler 4 $MIRROR_MODULES-deb
	echo $LINE
	echo $LINE
	echo
	sleep $sleepTime
	# grab source zips/debs for modules
	echo "Getting module tar.gz data now..."
	wget -r -l3 -Nc -nd -np -A.tar.gz $MIRROR_MODULES -e robots=off # || error_handler 4 $MIRROR_MODULES-tar.gz
	echo $LINE
	echo $LINE
	echo
	sleep $sleepTime
	# grab source zips/debs for modules
	echo "Getting module diff.gz data now..."
	wget -r -l3 -Nc -nd -np -A.diff.gz $MIRROR_MODULES -e robots=off # || error_handler 4 $MIRROR_MODULES-tar.gz
	echo $LINE
	echo $LINE
	echo
	sleep $sleepTime
	echo "Getting primary kernel debs now..."
	wget -r -l3 -Nc -nd -np -A.deb $MIRROR_MAIN -e robots=off # || error_handler 4 $MIRROR_MAIN-deb
	echo $LINE
	echo $LINE
	echo
	sleep $sleepTime
	echo "Getting kernel diff.gz data now..."
	# might as well include this for aptosid kernels because the src gz is small
	case $KERNEL_TYPE in
		liquorix)
			cd src-gz
			;;
	esac
	wget -r -l3 -Nc -nd -np -A.diff.gz $MIRROR_MAIN -e robots=off # || error_handler 4 $MIRROR_MAIN-diff.gz
	echo $LINE
	echo $LINE
	echo
	sleep $sleepTime
	echo "Getting kernel debian.tar.gz data now..."
	wget -r -l3 -Nc -nd -np -A.debian.tar.gz $MIRROR_MAIN -e robots=off # || error_handler 4
	echo $LINE
	echo $LINE
	echo
	sleep $sleepTime
	echo "Getting kernel debian.tar.bz2 data now..."
	wget -r -l3 -Nc -nd -np -A.debian.tar.bz2 $MIRROR_MAIN -e robots=off # || error_handler 4
	echo $LINE
	echo $LINE
	echo
	sleep $sleepTime
	echo "Getting kernel debian.tar.xz data now..."
	wget -r -l3 -Nc -nd -np -A.debian.tar.xz $MIRROR_MAIN -e robots=off # || error_handler 4
	case $KERNEL_TYPE in
		liquorix)
			cd ../
			;;
	esac
	echo $LINE
	echo $LINE
	echo
	sleep $sleepTime

	if [ -n "$MIRROR_EXTRA" ];then
		echo "Getting kbuild debs now..."
		wget -r -l3 -Nc -nd -np -A.deb $MIRROR_EXTRA -e robots=off # || error_handler 3 $MIRROR_EXTRA
		echo $LINE
		echo $LINE
		echo
		sleep $sleepTime
		echo "Getting kbuild gx data now..."
		wget -r -l3 -Nc -nd -np -A.gz $MIRROR_EXTRA -e robots=off # || error_handler 3 $MIRROR_EXTRA
		echo $LINE
		echo $LINE
		echo
		sleep $sleepTime
	fi
	echo "Done with kernel package data, continuing..."
}

move_files_to_directories()
{
	local kernelType='' gzDir=''

	case $KERNEL_TYPE in
		aptosid)
			kernelType='aptosid'
			;;
		liquorix)
			kernelType='liquorix'
			gzDir='src-gz/'
			;;
	esac

	echo "Transferring files to directories..."
	mv -f linux-image-${kernelType}*i386.deb 32-meta
	mv -f linux-headers-${kernelType}*i386.deb 32-meta
	# 2.6 packages for headers are dummies to update user systems
	mv -f linux-image-2.6-${kernelType}*i386.deb 32-meta
	mv -f linux-headers-2.6-${kernelType}*i386.deb 32-meta
	mv -f linux-image-${kernelType}*amd64.deb 64-meta
	mv -f linux-headers-${kernelType}*amd64.deb 64-meta
	# 2.6 packages for headers are dummies to update user systems
	mv -f linux-image-2.6-${kernelType}*amd64.deb 64-meta
	mv -f linux-headers-2.6-${kernelType}*amd64.deb 64-meta
	cp -f $gzDir*${KERNEL_MAIN}*.gz 32
	cp -f $gzDir*${KERNEL_MAIN}*.gz 32-pae
	cp -f $gzDir*$KERNEL_MAIN*.gz 64
	cp -f $gzDir*${KERNEL_MAIN}*.xz 32
	cp -f $gzDir*${KERNEL_MAIN}*.xz 32-pae
	cp -f $gzDir*$KERNEL_MAIN*.xz 64
	cp -f $gzDir*${KERNEL_MAIN}*.bz2 32
	cp -f $gzDir*${KERNEL_MAIN}*.bz2 32-pae
	cp -f $gzDir*$KERNEL_MAIN*.bz2 64
	cp -f *linux-support*.deb 32
	cp -f *linux-support*.deb 32-pae
	cp -f *linux-support*.deb 64
	mv -f *${KERNEL_MAIN}*pae*i386.deb 32-pae
	mv -f *${KERNEL_MAIN}*i386.deb 32
	mv -f *${KERNEL_MAIN}*amd64.deb 64
	cp -f linux-patch-${kernelType}* 32
	cp -f linux-patch-${kernelType}* 32-pae
	cp -f linux-patch-${kernelType}* 64
	echo "Completed download and handling of: $NEW_KERNEL_DIRECTORY"
}

add_update_installer_files()
{
	local fullKernelString32='' fullKernelString64='' fullKernelString32Pae=''

	case $KERNEL_TYPE in
		aptosid)
			fullKernelString32="$KERNEL_WORKING-aptosid-686"
			fullKernelString64="$KERNEL_WORKING-aptosid-amd64"
			;;
		liquorix)
			fullKernelString32="$KERNEL_WORKING-liquorix-686"
			fullKernelString32Pae="$KERNEL_WORKING-liquorix-686-pae"
			fullKernelString64="$KERNEL_WORKING-liquorix-amd64"
			;;
	esac

	echo $LINE
	echo 'Adding installer files and updating files...'
	cp $KERNEL_INSTALLER_DIR/install-kernel.sh 32/install-kernel.sh
	cp $KERNEL_INSTALLER_DIR/install-kernel.sh 32-pae/install-kernel.sh
	cp $KERNEL_INSTALLER_DIR/install-kernel.sh 64/install-kernel.sh

	sed -i 's/^KERNEL_VERSION=\".*\"/KERNEL_VERSION=\"'$fullKernelString32'\"/' 32/install-kernel.sh
	sed -i 's/^KERNEL_VERSION=\".*\"/KERNEL_VERSION=\"'$fullKernelString32Pae'\"/' 32-pae/install-kernel.sh
	sed -i 's/^KERNEL_VERSION=\".*\"/KERNEL_VERSION=\"'$fullKernelString64'\"/' 64/install-kernel.sh
	
	if [ -n "$GCC_ALT" ];then
		echo "Updating GCC data to use: $GCC_ALT"
		sed -i 's/^GCC_VERSION=\".*\"/GCC_VERSION=\"'$GCC_ALT'\"/' 32/install-kernel.sh
		sed -i 's/^GCC_VERSION=\".*\"/GCC_VERSION=\"'$GCC_ALT'\"/' 32-pae/install-kernel.sh
		sed -i 's/^GCC_VERSION=\".*\"/GCC_VERSION=\"'$GCC_ALT'\"/' 64/install-kernel.sh
	fi
}

make_zip_files()
{
	local contents=''
	local kernel32Zip='' kernel64Zip='' kernel32PaeZip=''

	case $KERNEL_TYPE in
		aptosid)
			kernel32Zip="$KERNEL_WORKING-aptosid-686.zip"
			kernel64Zip="$KERNEL_WORKING-aptosid-amd64.zip"
			;;
		liquorix)
			kernel32Zip="$KERNEL_WORKING-liquorix-686.zip"
			kernel32PaeZip="$KERNEL_WORKING-liquorix-686-pae.zip"
			kernel64Zip="$KERNEL_WORKING-liquorix-amd64.zip"
			;;
	esac

	echo $LINE
	echo 'Making 32 bit zip file now...'
	cd 32
	contents=$(ls)
	zip $kernel32Zip $contents
	echo 'Testing 32 bit kernel zip file for corruption...'
	unzip -t $kernel32Zip || error_handler 7 $kernel32Zip
	echo "32 bit kernel zip corruption test: passed"
	mv $kernel32Zip ../kernel-full-zips/
	
	echo 'Making 32-pae bit zip file now...'
	cd ../32-pae
	contents=$(ls)
	zip $kernel32PaeZip $contents
	echo 'Testing 32-pae bit kernel zip file for corruption...'
	unzip -t $kernel32PaeZip || error_handler 7 $kernel32PaeZip
	echo "32-pae bit kernel zip corruption test: passed"
	mv $kernel32PaeZip ../kernel-full-zips/

	echo 'Making 64 bit zip file now...'
	cd ../64
	contents=$(ls)
	zip $kernel64Zip $contents
	echo 'Testing 64 bit kernel zip file for corruption...'
	unzip -t $kernel64Zip || error_handler 7 $kernel64Zip
	echo '64 bit kernel zip corruption test: passed'
	mv $kernel64Zip ../kernel-full-zips/
}

clean_up()
{
	cd ../
	rm -f robots.txt
}

finish_it_up()
{
	echo $LINE
	echo 'OK, all finished. Remember to add new kernels to sm-lib-kernel global and upload the zips.'
}

########################################################################
#### EXECUTE
########################################################################

get_options "$@"
set_values

if [ "$B_REDO" == 'true' ];then
	#start_up_tests
	#check_kernel_exists
	create_kernel_directory
	create_sub_directories
	#download_kernel_files
	move_files_to_directories
	add_update_installer_files
	make_zip_files
	clean_up
	finish_it_up
elif [ "$B_SKIP_ZIP" == 'true' ];then
	start_up_tests
	check_kernel_exists
	create_kernel_directory
	create_sub_directories
	download_kernel_files
	#move_files_to_directories
	add_update_installer_files
	#make_zip_files
	clean_up
	finish_it_up
else
	start_up_tests
	check_kernel_exists
	create_kernel_directory
	create_sub_directories
	download_kernel_files
	move_files_to_directories
	add_update_installer_files
	make_zip_files
	clean_up
	finish_it_up
fi
exit 0
